///////////////////////////////////////////////////////////
//  GameWindow.h
//  Implementation of the Class GameWindow
//  Created on:      11-Jan-2015 4:13:27 PM
//  Original author: Eng. Ahmed Yasser
///////////////////////////////////////////////////////////

#if !defined(EA_FA59ACAA_7CE9_4b66_9EE3_02AF133877A7__INCLUDED_)
#define EA_FA59ACAA_7CE9_4b66_9EE3_02AF133877A7__INCLUDED_

#include <vector>

#include "IGameWindow.h"
#include "IGameWindowObserver.h"

namespace EngineGame
{
	namespace EngineCore
	{
		/**
		 * The game window that represent a window in windows environment
		 * @author Eng. Ahmed Yasser
		 * @version 1.0
		 * @updated 12-Jan-2015 12:01:55 PM
		 */
		class GameWindow : public EngineGame::EngineCore::IGameWindow
		{

		public:
			GameWindow();
			virtual ~GameWindow();
			GameWindow(const GameWindow& theGameWindow);

			/**
			 * Add a new game window observer
			 * 
			 * @param gameWindowObserver    the window observer
			 */
			void addGameWindowObserver(IGameWindowObserver* gameWindowObserver);
			/**
			 * clear all game window observers
			 */
			void clearGameWindowObservers();
			/**
			 * Creates a new window based on the settings supplied
			 * 
			 * @param hInstance    The instance handle of the application
			 * @param windowTitle    The title of the window
			 * @param windowWidth    The width of the window
			 * @param windowHeight    The height of the window
			 */
			virtual void createWindow(HINSTANCE hInstance, std::string windowTitle, int windowWidth, int windowHeight);
			/**
			 * Destroy the window and removes its resources from the memory
			 */
			virtual void destroyWindow();
			/**
			 * Returns the instance of the application that created  the window
			 */
			HINSTANCE getAppInstance();
			/**
			 * Returns the handle of the window that created.
			 */
			HWND getHWnd();
			/**
			 * returns the window height
			 */
			int getWindowHeight();
			/**
			 * returns the window rectangle
			 */
			RECT getWindowRect();
			/**
			 * Returns the window title
			 */
			std::string getWindowTitle();
			/**
			 * Returns the window width
			 */
			int getWindowWidth();
			/**
			 * Process the massages in the window
			 */
			virtual void processEvents();
			/**
			 * Remove the game window observer
			 * 
			 * @param gameWindowObserver
			 */
			void removeGameWindowObserver(IGameWindowObserver* gameWindowObserver);

		protected:
			/**
			 * The instance of the application that created the window
			 */
			HINSTANCE _hInstance;
			/**
			 * The handle of the window that is created
			 */
			HWND _hWnd;
			/**
			 * The rectangle of the window created
			 */
			RECT _windowRect;
			/**
			 * The title of the window created
			 */
			std::string _windowTitle;
			/**
			 * The list of all game window observers that is attached to the game window
			 */
			std::vector<IGameWindowObserver*>_gameWindowObservers;

			/**
			 * The default window message handler
			 * 
			 * @param hWnd    The handle of the window that will be handle events
			 * @param message    The message that will be handled
			 * @param wParam    The wparam of the message
			 * @param lParam    The lparam of the message
			 */
			virtual LRESULT CALLBACK wndProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam);

		private:
			/**
			 * The default window message handler
			 * 
			 * @param hWnd    The handle of the window that will be handle events
			 * @param message    The message that will be handled
			 * @param wParam    The wparam of the message
			 * @param lParam    The lparam of the message
			 */
			static LRESULT CALLBACK staticWndProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam);

		};

	}

}
#endif // !defined(EA_FA59ACAA_7CE9_4b66_9EE3_02AF133877A7__INCLUDED_)
